
//
//  Receiver.m
//  运行时方法的实现
//
//  Created by MyMac on 15/8/25.
//  Copyright (c) 2015年 MyMac. All rights reserved.
//

#import "Receiver.h"
#import <objc/runtime.h>
#import "Forwording.h"
@implementation Receiver
//-(void)sendMessageWithString:(NSString*)name;
//{
//
//    NSLog(@"%@",name);
//
//}

//当方法没有实现时，，，在抛出异常前，有三次机会拯救程序
//1.Method Resolution
//2.Fast Forwarding
//3.Normal Forwarding


#warning 1.Method Resolution
//在运行时调用+(BOOL)resolveClassMethod:(SEL)sel或者+(BOOL)resolveInstanceMethod:(SEL)sel动态的添加方法，并且返回YES，系统在运行时会重新启动一次消息发送过程
//
//+(BOOL)resolveInstanceMethod:(SEL)sel
//{
//    if(sel==@selector(sendMessageWithString:)||sel==@selector(addmessage:)){
// 利用运行时动态的添加方法
//        class_addMethod([self class], sel, imp_implementationWithBlock(^(id self,SEL _cmd,NSString*word){
//        
//            NSLog(@"%@",word);
//        
//        }), "v@*");//v@*代表方法的参数和返回值
//
//    
//    
//    
//    }
//
//    return YES;
//
//
//}
#warning 2.如果+(BOOL)resolveInstanceMethod:(SEL)sel返回NO；运行时就跳转到下一步（MEssage Forwarding 如果目标对象实现-(id)forwardingTargetForSelector:(SEL)aSelector方法，只要这个方法不是返回nil或self，也会启动消息重发过程，，把这消息转发给"其他"对象来处理
//-(id)forwardingTargetForSelector:(SEL)aSelector
//{
//    if(aSelector==@selector(sendMessageWithString:)||aSelector==@selector(addmessage:)){
//    
//    
//        return [Forwording new];//消息转发，，将消息给Forwording的对象处理
//    
//    
//    }
//    return nil;
//
//
//
//
//}
#warning 3.如果-(id)forwardingTargetForSelector:(SEL)aSelector返回是self或nil，，，那么消息将会交给Normol  Fowading处理，因为这一步不用创建NSInvocation，所以是fast
#warning 这种方式实际上还是消息转发
//在 iOS中可以直接调用某个对象的消息方式有两种：

//一种是performSelector:withObject；
//
//再一种就是NSInvocation。如果参数有两个，或者方法有返回值，那么就只能用NSInvocation

/**
 *  获取函数的参数和返回值，如果返回成功，，系统会创建一个NSInvocation对象，bingqie调用-(void)forwardInvocation:(NSInvocation *)anInvocation
 *
 *  @param aSelector <#aSelector description#>
 *
 *  @return <#return value description#>
 */

-(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector
{
    NSLog(@"%@",NSStringFromSelector(aSelector));
    NSMethodSignature*methodSignature=[super methodSignatureForSelector:aSelector];
    if(!methodSignature){
        methodSignature=[NSMethodSignature signatureWithObjCTypes:"v@:*"];
    
    
    
    }


    return methodSignature;


}
-(void)forwardInvocation:(NSInvocation *)anInvocation
{
    Forwording*messageForwording=[Forwording new];
    if([messageForwording respondsToSelector:@selector(sendMessageWithString:)]){
        [anInvocation invokeWithTarget:messageForwording];
    
    
    
    }

}

@end
